// skype_event_test.cpp : Defines the entry point for the console application.
//

#include "main.h"

using namespace SKYPE4COMLib;

static _ATL_FUNC_INFO AttachmentStatusInfo =  {CC_STDCALL,VT_EMPTY,1,{VT_I4}};
static _ATL_FUNC_INFO CommandInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH|VT_BYREF}};
static _ATL_FUNC_INFO ReplyInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH|VT_BYREF}};
static _ATL_FUNC_INFO ErrorInfo = {CC_STDCALL,VT_EMPTY,3,{VT_DISPATCH|VT_BYREF,VT_I4,VT_BSTR}};
static _ATL_FUNC_INFO ConnectionStatusInfo = {CC_STDCALL,VT_EMPTY,1,{VT_I4}};
static _ATL_FUNC_INFO UserStatusInfo = {CC_STDCALL,VT_EMPTY,1,{VT_I4}};
static _ATL_FUNC_INFO OnlineStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};
static _ATL_FUNC_INFO CallStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};
static _ATL_FUNC_INFO CallHistoryInfo = {CC_STDCALL,VT_EMPTY,0,{VT_EMPTY}};
static _ATL_FUNC_INFO MuteInfo = {CC_STDCALL,VT_EMPTY,1,{VT_BOOL}};
static _ATL_FUNC_INFO MessageStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};
static _ATL_FUNC_INFO MessageHistoryInfo = {CC_STDCALL,VT_EMPTY,1,{VT_BSTR}};


class CSkypeEventListener : public IDispEventSimpleImpl<1, CSkypeEventListener, &__uuidof(_ISkypeEvents)>
{
public:
	CSkypeEventListener() {};

	BEGIN_SINK_MAP(CSkypeEventListener)

		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 1, &Command,  &CommandInfo)

		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 2, &Reply,  &ReplyInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 3, &Error,  &ErrorInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 4, &AttachmentStatus,  &AttachmentStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 5, &ConnectionStatus,  &ConnectionStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 6, &UserStatus,  &UserStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 7, &OnlineStatus,  &OnlineStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 8, &CallStatus,  &CallStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 10, &Mute,  &MuteInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 11, &MessageStatus,  &MessageStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 12, &MessageHistory,  &MessageHistoryInfo)

	END_SINK_MAP()



	//void __stdcall Command(ICommand* pCommand) {

	//	_tprintf(_T("C(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetCommand());

	//}

	//void __stdcall Reply(ICommand* pCommand) {

	//	_tprintf(_T("R(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());

	//}

	void __stdcall Error(ICommand* pCommand, LONG Number, BSTR Description)
	{
		_tprintf(_T("E(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());
	}

	void __stdcall AttachmentStatus(TAttachmentStatus Status)
	{
		_tprintf(_T("Attachment status %d\n"), Status);
	}

	void __stdcall ConnectionStatus(TConnectionStatus Status)
	{
		_tprintf(_T("Connection status %d\n"), Status);
	}

	void __stdcall UserStatus(TUserStatus Status)
	{
		_tprintf(_T("User status %d\n"), Status);
	}

	void __stdcall OnlineStatus(IUser* pUser, TOnlineStatus Status)
	{
		_tprintf(_T("User %s status %d\n"), (LPCTSTR)pUser->GetHandle(), Status);
	}

	void __stdcall CallStatus(ICall* pCall, TCallStatus Status)
	{
		_tprintf(_T("Call %d status %d\n"), pCall->GetId(), Status);
	}

	void __stdcall CallHistory()
	{
		_tprintf(_T("Call history changed\n"));
	}

	void __stdcall Mute(VARIANT_BOOL Status)
	{      
		if (Status == VARIANT_TRUE)
		{
			_tprintf(_T("Mute on\n"));
		} 
		else
		{
			_tprintf(_T("Mute off\n"));
		}
	}

	void __stdcall MessageStatus(IChatMessage* pMessage, TChatMessageStatus Status)
	{
		_tprintf(_T("Message id = %d, status %d\n"), pMessage->GetId(), Status);
		_bstr_t body = pMessage->GetBody();
		_tprintf(_T("	body - %s\n"), (LPCTSTR)body);
	}

	void __stdcall MessageHistory(BSTR Username)
	{
		_tprintf(_T("Message history changed %s\n"), (LPCTSTR)_bstr_t(Username));
	}
};


int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT hr = S_OK;

	CoInitialize(NULL);

	// Create
	ISkypePtr pSkype;
	hr = pSkype.CreateInstance(__uuidof(SKYPE4COMLib::Skype));

	//ISkypePtr pSkype(__uuidof(SKYPE4COMLib::Skype));

	// Create sink
	CSkypeEventListener* pSinkSkype = new CSkypeEventListener();

	// Start client
	IClientPtr pClient = pSkype->GetClient();
	if (pClient->IsRunning == VARIANT_FALSE)
		pClient->Start(VARIANT_FALSE, VARIANT_FALSE);

	// Connect events
	hr = pSinkSkype->DispEventAdvise(pSkype);

	// Send attach request
	pSkype->Attach(6, VARIANT_FALSE);

	// Wait attached status
	TAttachmentStatus attachStatus = pSkype->GetAttachmentStatus();
	while (attachStatus != TAttachmentStatus::apiAttachSuccess &&
		attachStatus != TAttachmentStatus::apiAttachRefused)
	{
		Sleep(1000);
		attachStatus = pSkype->GetAttachmentStatus();
	}

	// Message loop
	MSG msg;
	while (GetMessage( &msg, NULL, 0, 0 )) 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	// Disconnect events
	pSinkSkype->DispEventUnadvise(pSkype);

	// Destroy
	pSkype = NULL;
	CoUninitialize();

	getchar();
	return 0;
}

